﻿package net.L4cd.game
{
	public class iLLK 
	{
		private var _map:Array;
		private var x_max:uint;
		private var y_max:uint;
		private var type:Array;
		
		
		public function iLLK():void
		{
			_map = null;
		}
		
		public function set map(_value:Array):void 
		{
			_map = _value;
			x_max = 0
			y_max = 0
			try{
				x_max = _map.length
				y_max = _map[0].length
			}catch(e:Error){}
			getType()
		}
		
		public function get map():Array 
		{
			return _map;
		}
		private function getType():void
		{
			type = new Array()
			for(var x_:uint = 0;x_<x_max;x_++)
			{
				for(var y_:uint = 0;y_<y_max;y_++)
				{
					type[String(_map[x_][y_].type)] = "L4cd.Net"
				}
			}
		}
		
		
		public function getLink():Array
		{
			for( var i:String in type){
				if(i == "-1")continue
				var mapArray:Array = getTypeMap(i)
				if(!mapArray)continue
				for(var k:uint = 0;k<mapArray.length;k++)
				{
					for(var j:uint = 0;j<mapArray.length;j++)
					{
						if(k==j)continue
						var p:Array = link(mapArray[k],mapArray[j],true)
						if(p)return [mapArray[k],mapArray[j]]
					}
				}
				
			}
			return null
		}
		
		private function getTypeMap(_type:String):Array{
			var __map:Array = new Array()
			for(var x_:uint = 0;x_<x_max;x_++)
			{
				for(var y_:uint = 0;y_<y_max;y_++)
				{
					if(_map[x_][y_].type == _type && check1([x_,y_],_type))__map.push([x_,y_])
				}
			}
			return __map.length>0?__map:null
		}
		
		private function check1(arr:Array,_type:String):Boolean{
			if(_map[arr[0]][arr[1]-1].type == -1 || _map[arr[0]][arr[1]-1].type == _type)return true
			if(_map[arr[0]+1][arr[1]].type == -1 || _map[arr[0]+1][arr[1]].type == _type)return true
			if(_map[arr[0]][arr[1]+1].type == -1 || _map[arr[0]][arr[1]+1].type == _type)return true
			if(_map[arr[0]-1][arr[1]].type == -1 || _map[arr[0]-1][arr[1]].type == _type)return true
			return false
		}
		
		public function link(a_:Array,b_:Array,test:Boolean=false):Array 
		{
			var a:Object = _map[a_[0]][a_[1]]
			var b:Object = _map[b_[0]][b_[1]]
			if(!_map)return null
			if (a.type != b.type)return null
			if (a.x == b.x && a.y == b.y)return null
			var path:Array = new Array();
			var t1:uint,t2:uint,v:int;
			var _p:Array;
			//横
			for (var x_:uint=0; x_<x_max; x_++) {
				_p = new Array();
				//循环A
				v = x_ < a.x?-1:1;
				t1 = a.x;
				t2 = x_;
				for (; t1 != t2; t1 += v) {
					_p.push([t1,a.y]);
				}
				//循环A2B
				v = a.y < b.y?1:-1;
				t1 = a.y;
				t2 = b.y;
				for (; t1 != t2; t1 += v) {
					_p.push([x_,t1]);
				}
				//循环B
				v = x_ < b.x?1:-1;
				t1 = x_;
				t2 = b.x;
				for (; t1 != t2; t1 += v) {
					_p.push([t1,b.y]);
				}
				_p.shift();
				path.push(_p);
			}
			//竖
			for (var y_:uint=0; y_<y_max; y_++) {
				_p = new Array();
				//循环A
				v = y_ < a.y?-1:1;
				t1 = a.y;
				t2 = y_;
				for (; t1 != t2; t1 += v) {
					_p.push([a.x,t1]);
				}
				//循环A2B
				v = a.x < b.x?1:-1;
				t1 = a.x;
				t2 = b.x;
				for (; t1 != t2; t1 += v) {
					_p.push([t1,y_]);
				}
				//循环B
				v = y_ < b.y?1:-1;
				t1 = y_;
				t2 = b.y;
				for (; t1 != t2; t1 += v) {
					_p.push([b.x,t1]);
				}
				_p.shift();
				path.push(_p);
			}
			path = path.filter(pathFilter);
			if (path.length > 0) {
				path.sort(pathSort);
				if(!test){
					a.type = -1;
					b.type = -1;
				}
				return path[0];
			} else {
				return null;
			}
		}
		
		private function pathFilter(a:Array,b:uint,c:Array):Boolean 
		{
			for (var i:uint = 0; i<a.length; i++) {
				if (_map[a[i][0]][a[i][1]].type != -1) {
					return false;
				}
			}
			return true;
		}
		
		private function pathSort(a:Array,b:Array):int {
			return a.length < b.length?-1:1;
		}

	}
}